We propose a rank-based procedure for batch adjustment. The basic idea is find a transformation for the batch 1 nAb readouts so that when they are mixed with batch 2 nAb readouts and rank together, the ranking is consistent with the ranking of the corresponding bAb.
Let f(x) be the mapping/correction we will apply to batch 1 nAb. The choice of f(x) is not too important for now - let’s just assume it is a truncated linear shift: f(x)=x-c if x-c>=lod, otherwise lod/2. We can solve an optimization problem,
\(\hat{c} = argmin_c L(rank_{bAb}, rank_{nAb}(c)),\)
where \(rank_{bAb}\) is the rank of each ptid in bAb for all ptids. \(rank_{nAb}\) is defined similarly based on nAb. It is obviously a function of c. The loss function \(L\) can be L1 norm of the difference or 1 - Spearman correlation coefficient. Optimization can be done by exhaustive search on a grid of candidate values for c.
We test the procedure on two bAb readouts. Since there are no batch effects for bAb, the truth \(c\) is 0. \(\hat{c}\)s are between -0.05 and 0.05.
## Day43bindSpike_beta Day43bindSpike
## .trt = 0
## Estimated c is -0.05.
## .trt = 1
## Estimated c is 0.05.
## Day43bindSpike_omicron Day43bindSpike
## .trt = 0
## Estimated c is 0.
## .trt = 1
## Estimated c is 0.
## Day43bindSpike_beta Day43bindSpike_omicron
## .trt = 0
## Estimated c is 0.05.
## .trt = 1
## Estimated c is 0.
## cors cors cors cors cors cors
## -0.2 0.9785259 0.9329043 0.9522915 0.9210569 0.9558593 0.9379584
## -0.15 0.9809836 0.9488171 0.9532039 0.9343516 0.9586193 0.9518165
## -0.1 0.9827157 0.9614297 0.9539236 0.9455725 0.9606339 0.9626421
## -0.05 0.9837642 0.9691555 0.9538105 0.9551113 0.9620651 0.9682470
## 0 0.9836226 0.9739456 0.9550575 0.9607232 0.9628142 0.9708274
## 0.05 0.9826297 0.9739530 0.9533883 0.9593071 0.9628548 0.9685077
## 0.1 0.9799940 0.9699903 0.9508359 0.9553525 0.9613265 0.9624538
## 0.15 0.9761451 0.9612550 0.9474048 0.9481777 0.9584664 0.9517670
## 0.2 0.9712363 0.9503345 0.9429200 0.9357750 0.9543220 0.9384582
We permute the nAbBatch value so that there are no batch effects. Again, \(\hat{c}\)s are between -0.05 and 0.05.
## Day43pseudoneutid50 Day43bindSpike
## .trt = 0
## Estimated c is 0.1.
## .trt = 1
## Estimated c is -0.05.
## Day43pseudoneutid50_B.1.351 Day43bindSpike_beta
## .trt = 0
## Estimated c is 0.
## .trt = 1
## Estimated c is 0.1.
## Day43pseudoneutid50_BA.1 Day43bindSpike_omicron
## .trt = 0
## Estimated c is 0.05.
## .trt = 1
## Estimated c is -0.1.
## cors cors cors cors cors cors
## -0.2 0.8925163 0.7665309 0.8791353 0.7331098 0.8525162 0.7450699
## -0.15 0.8957855 0.7730001 0.8796387 0.7419011 0.8536845 0.7474799
## -0.1 0.8979592 0.7796600 0.8798782 0.7490732 0.8546260 0.7495013
## -0.05 0.9010002 0.7812792 0.8800577 0.7546109 0.8554883 0.7492956
## 0 0.9054909 0.7811042 0.8874692 0.7578904 0.8841133 0.7474004
## 0.05 0.9071018 0.7783605 0.8864808 0.7592841 0.8844400 0.7435609
## 0.1 0.9077395 0.7747085 0.8850620 0.7597169 0.8842156 0.7395634
## 0.15 0.9077247 0.7676543 0.8835801 0.7592564 0.8834012 0.7315784
## 0.2 0.9072224 0.7599019 0.8818872 0.7557071 0.8829441 0.7231967
The bAb levels between the two batches are the similar in vaccine (likely due to saturation), but not in placebo.
Compute 6 \(\hat{c}\): 3 pairs of nAb-bAb markers \(\times\) {vaccine, placebo}. Most of \(\hat{c}\)s are around 0.2, except for Day43pseudoneutid50_B.1.351 vs Day43bindSpike_beta in the placebo, which is 0.4. As the following control experiments, the uncertainty of \(\hat{c}\) is plus minus 0.05, which is about 12%.
## Day43pseudoneutid50 Day43bindSpike
## .trt = 0
## Estimated c is 0.25.
## .trt = 1
## Estimated c is 0.15.
## Day43pseudoneutid50_B.1.351 Day43bindSpike_beta
## .trt = 0
## Estimated c is 0.35.
## .trt = 1
## Estimated c is 0.25.
## Day43pseudoneutid50_BA.1 Day43bindSpike_omicron
## .trt = 0
## Estimated c is 0.1.
## .trt = 1
## Estimated c is 0.15.
## cors cors cors cors cors cors
## 0 0.9054909 0.7811042 0.8874692 0.7578904 0.8802848 0.7474004
## 0.05 0.9065954 0.7872345 0.8892129 0.7693967 0.8814059 0.7518442
## 0.1 0.9077372 0.7912281 0.8912890 0.7779845 0.8821379 0.7546740
## 0.15 0.9080635 0.7921773 0.8928213 0.7849530 0.8817642 0.7559438
## 0.2 0.9081916 0.7909736 0.8939066 0.7911121 0.8806951 0.7556530
## 0.25 0.9088983 0.7854361 0.8946506 0.7954748 0.8786258 0.7531893
## 0.3 0.9077069 0.7791682 0.8961218 0.7952811 0.8783239 0.7478293
## 0.35 0.9061171 0.7708514 0.8964476 0.7944120 0.8781668 0.7428253
## 0.4 0.9033713 0.7609891 0.8963932 0.7918961 0.8710207 0.7347568
## 0.45 0.9013384 0.7479404 0.8945476 0.7866185 0.8600705 0.7260716
## 0.5 0.8988865 0.7304793 0.8931475 0.7788355 0.8510417 0.7146396
Note that BA.4.5 ID50 is missing in batch 2. The missing values are imputed in dat_proc.
Compute 6 \(\hat{c}\): 3 pairs of nAb-bAb markers \(\times\) {vaccine, placebo}. Most of \(\hat{c}\)s are around 0.2. For the rest, visual examination of the curves suggest 0.2 is fine.
## Day43pseudoneutid50 Day43bindSpike
## .trt = 0
## Estimated c is 0.05.
## .trt = 1
## Estimated c is 0.15.
## Day43pseudoneutid50_B.1.351 Day43bindSpike_beta
## .trt = 0
## Estimated c is 0.1.
## .trt = 1
## Estimated c is 0.2.
## Day43pseudoneutid50_BA.1 Day43bindSpike_omicron
## .trt = 0
## Estimated c is 0.1.
## .trt = 1
## Estimated c is 0.2.
## cors cors cors cors cors cors
## 0 0.8869295 0.7854545 0.7459050 0.7741649 0.6406716 0.7055507
## 0.05 0.8870866 0.7886200 0.7456610 0.7774521 0.6408062 0.7079606
## 0.1 0.8813531 0.7912765 0.7479248 0.7804541 0.6409640 0.7092692
## 0.15 0.8810270 0.7914422 0.7476528 0.7818371 0.6316084 0.7101117
## 0.2 0.8812607 0.7890304 0.7465509 0.7834252 0.6316862 0.7114620
## 0.25 0.8795599 0.7867487 0.7436692 0.7831432 0.6318730 0.7108504
## 0.3 0.8788198 0.7831986 0.7408387 0.7813961 0.6319900 0.7102923
## 0.35 0.8771533 0.7787083 0.7400258 0.7799276 0.6320101 0.7075426
## 0.4 0.8720610 0.7717530 0.7350622 0.7772011 0.6321267 0.7063260
## 0.45 0.8658855 0.7633683 0.7344090 0.7705285 0.6321688 0.7022174
## 0.5 0.8619773 0.7567010 0.7336379 0.7636391 0.6279473 0.6976534
Compute 6 \(\hat{c}\): 3 pairs of nAb-bAb markers \(\times\) {vaccine, placebo}.
## Day22pseudoneutid50 Day22bindSpike
## .trt = 0
## Estimated c is 0.2.
## .trt = 1
## Estimated c is 0.15.
## Day22pseudoneutid50_B.1.351 Day22bindSpike_beta
## .trt = 0
## Estimated c is 0.15.
## .trt = 1
## Estimated c is 0.25.
## Day22pseudoneutid50_BA.1 Day22bindSpike_omicron
## .trt = 0
## Estimated c is 0.
## .trt = 1
## Estimated c is 0.3.
## cors cors cors cors cors cors
## 0 0.8963640 0.8702676 0.8556838 0.8927821 0.8133983 0.7873451
## 0.05 0.8984387 0.8736525 0.8567153 0.8969138 0.8062452 0.7927314
## 0.1 0.8996603 0.8761328 0.8577632 0.8997225 0.8043172 0.7965694
## 0.15 0.9004231 0.8771934 0.8588173 0.9026452 0.7990231 0.7985329
## 0.2 0.9014694 0.8757427 0.8550085 0.9036725 0.7994047 0.8012821
## 0.25 0.9013253 0.8734724 0.8516485 0.9044762 0.8018054 0.8021577
## 0.3 0.9002793 0.8698837 0.8525377 0.9041229 0.7997988 0.8033546
## 0.35 0.8997484 0.8653652 0.8513406 0.9019992 0.7907938 0.8027599
## 0.4 0.8981680 0.8603445 0.8502148 0.8993439 0.7842630 0.8018347
## 0.45 0.8948812 0.8528467 0.8479691 0.8942824 0.7747804 0.7999218
## 0.5 0.8926269 0.8452714 0.8388966 0.8893614 0.7700157 0.7983817
Compute 6 \(\hat{c}\): 3 pairs of nAb-bAb markers \(\times\) {vaccine, placebo}.
## Day22pseudoneutid50 Day22bindSpike
## .trt = 0
## Estimated c is 0.
## .trt = 1
## Estimated c is 0.
## Day22pseudoneutid50_B.1.351 Day22bindSpike_beta
## .trt = 0
## Estimated c is 0.
## .trt = 1
## Estimated c is 0.1.
## Day22pseudoneutid50_BA.1 Day22bindSpike_omicron
## .trt = 0
## Estimated c is 0.05.
## .trt = 1
## Estimated c is 0.05.
## cors cors cors cors cors cors
## 0 0.8483396 0.8022664 0.7398289 0.8064833 0.6171048 0.7852087
## 0.05 0.8469117 0.7997633 0.7395737 0.8067993 0.6172135 0.7869468
## 0.1 0.8451510 0.7968423 0.7395813 0.8077327 0.6105130 0.7862463
## 0.15 0.8431886 0.7922300 0.7390708 0.8073027 0.6105974 0.7868521
## 0.2 0.8407056 0.7860199 0.7338124 0.8059489 0.6106489 0.7867886
## 0.25 0.8386536 0.7782669 0.7311149 0.8034312 0.6106640 0.7851039
## 0.3 0.8352929 0.7690329 0.7264356 0.7992612 0.6034784 0.7830844
## 0.35 0.8320552 0.7592667 0.7204096 0.7947157 0.6034739 0.7800082
## 0.4 0.8252807 0.7477609 0.7166780 0.7888104 0.5980230 0.7762134
## 0.45 0.8134565 0.7348555 0.7110296 0.7824516 0.5978930 0.7718248
## 0.5 0.8047598 0.7225258 0.7076478 0.7757199 0.5978211 0.7670578